ReadNCFile2 with Token Modifier
The CNC12_TokenModifier.project
sample project is located in the installation directory of CODESYS under ..\CODESYS SoftMotion\Examples
.
This example shows how to modify the G-code during import in order to convert the unit of path velocity (F-word) from mm/min to mm/s. This is done by inserting the G-code 1/60.0 *
before the velocity value while the G-code for the F-word is read. F6000
then becomes F 1/60.0 * 6000
, which is later processed by the SMC_NCInterpreter
function block to F100
. In simple cases, you could skip the multiplication by 1/60
and simply adjust the value (for example, from 6000
to 100
). However, multiplication is more general because it also works when variables are used. F $SPEED$
becomes F 1/60.0 * $SPEED$
.
Structure of the application
As usual for CNC applications, the application consists of path processing (CNC_PreparePath
program) and interpolation (CNC
program). Because the interpolation is not different from the other examples, it will not be discussed further here.
Path processing is called cyclically every 20 ms in the low-priority PathTask
. The interpolation is called cyclically every 4 ms in the high-priority MotionTask
. The background task VISU_TASK
is defined for the visualization.
You can start processing the G-code in the visualization. The G-code and the movement of the machine (3D gantry) are displayed on the right side of the visualization.
The G-code
CNC_PathSpeed
N10 G01 X1000 F6000 N20 Y1000
In this G-code, the path velocity in block N10
is set with F6000
to 6000 mm/min. However, the CNC function blocks expect the path velocity in mm/s. Two linear movements are commanded, first to X=1000
and then to X=1000, Y=1000
.
Token processing
The SMC_ReadNCFile2
and SMC_ReadNCFromStream
function blocks provide the capability of performing your own transformations when the G-code is read. Here we are using with the SMC_ITokenModifier
interface, which is passed via the aTokenModifier
input.
This interface works on "tokens". These are the basic parts of the G-code into which the G-code text is subdivided when the processing is started.
N50 G36 O$plc_variable$ D'TextTest' X-1 (Comment)
This G-code is subdivided as follows:
Text | SMC_TOKENTYPE | SMC_TOKENVALUE |
---|---|---|
| identifer | stValue = 'N' |
| number | fValue = 50.0 |
| identifer | stValue = 'G' |
| number | fValue = 36.0 |
| identifer | stValue = 'O' |
| variable | stValue = 'plc_variable' |
| identifer | stValue = 'D' |
| strLiteral | stValue = 'TextTest' |
| identifer | stValue = 'X' |
| operator | stValue = '-' |
| number | fValue = 1.0 |
Information which is not required for further processing (for example, whitespace characters, line breaks, and comments) does not appear in the list of tokens.
When the SMC_ITokenModifier
interface is implemented, the list of tokens can be adapted by adding new tokens, deleting tokens, and changing the values of tokens.
Start
: Initialization of the function block. The internal state is reset.Call
: Call of this method while the G-code is being processed. Tokens can be read and removed from the input queue and added to the output queue.
Implementation
All tokens are moved from the input queue to the output queue.
If an F-word is detected, then two new tokens,
1/60
and*
, are added after the token for "F" and before the token for the velocity value.
The Call
method contains the logic to process the tokens. It is helpful to first move the tokens from the input queue (tokensIn
) to a temporary queue (m_tmpQueue
), process them there, and then move them to the output queue (tokensOut
). The temporary queue is not absolutely necessary to adapt the path velocity, but it simplifies the program structure in more complicated cases.
Method: Call
At first, the system waits in the STATE_RUNNING
state until processing can start (when tokens are available in the input queue and there is still space in the output queue).
IF NOT SMC_NC_CanProcessTokens(tokensIn, tokensOut) THEN // Wait until processing can proceed RETURN; END_IF
Then a token is moved from the input queue to the temporary queue.
IF m_tmpQueue.IsEmpty() THEN // Move the next token from the in-queue to the tmp-queue. pt := tokensIn.GetFromStart(0); m_tmpQueue.Append(pt^); tokensIn.RemoveFirst(); END_IF
The actual processing is done in the ConvertSpeed
method.
IF NOT m_tmpQueue.IsEmpty() THEN // The actual processing is done here ConvertSpeed(); END_IF
At the end of the method, a token is moved from the temporary queue to the output queue.
Method: ConvertSpeed
The first token from the temporary queue is checked.
If an identifier with the value F
is found, then two additional tokens are added: the number 1/60.0
and the operator *
.
(The size of the temporary queue is selected in such a way that two more tokens fit into the queue in addition to the one token from the input queue).
tk := m_tmpQueue.GetFromStart(0)^; IF tk.tokenType = SMC_TokenType.identifier THEN tk.GetString(pbyString => pby, iSize => iSize); // 70 = ASCII code for F (path velocity) IF iSize = 1 AND pby^ = 70 THEN // Insert the number 1/60 SMC_Token_InitNumber( tk:= tkNumber, value:= 1/60.0, srcPos:= tk.srcPos); m_tmpQueue.Append(tkNumber); // Insert operator '*' for multiplication SMC_Token_InitOperator( tk:= tkOperator, value:= '*', srcPos:= tk.srcPos); m_tmpQueue.Append(tkOperator); END_IF END_IF
Commissioning
Build the application and download it to a controller.
Start the application, switch to the visualization, and press
Start
.